5. SystemVerilog Threads

svThread.png


fork.png


1. 进程概述

进程或线程是作为独立实体执行的任何代码片段。在SystemVerilog中,fork-join块用于创建并行运行的不同线程。以下是几种不同类型的进程及其描述:

进程 描述
fork-join 只有所有子线程执行完毕时,父线程才会执行
fork-join_any 只有任何一个子线程执行完毕时,父线程才会执行
fork-join_none 父线程与子线程并行执行
wait fork 使父线程等待所有子线程执行完毕
disable fork 当执行disable fork时,会终止所有子线程的执行

2. fork-join

fork-join结构支持并行线程。在fork-join进程中,只有当所有子线程完成执行时,父线程才会继续执行。

语法:

fork 
  线程1 
  线程2 
  线程3
join

示例代码:

$display("[%0t] Thread_T1: a的值为%0d,b的值为%0d,c的值为%0d,d的值为%0d", $time, a, b, c, d);
fork:FORK_F1 
  begin:BEGIN_B2 
    #1 a <= b; 
    b <= 7; 
    $monitor("[%0t] Thread-T2: a的值为%0d,b的值为%0d,c的值为%0d,d的值为%0d", $time, a, b, c, d); 
    #1 ->e1; 
    c = b; 
  end:BEGIN_B2 
  begin:BEGIN_B3 
    wait(e1.triggered); 
    $display("[%0t] 事件已触发", $time); 
    begin:BEGIN_B4 
      #1 d = c; 
    end:BEGIN_B4 
  end:BEGIN_B3 
join:FORK_F1 
$display("[%0t] Thread_T3: a的值为%0d,b的值为%0d,c的值为%0d,d的值为%0d", $time, a, b, c, d);

Pasted image 20250318222055.png

3. fork-join_any

fork-join_any结构允许父线程在任何一个子线程完成执行后继续执行。这意味着即使有多个子线程,只要其中一个完成,父线程就会继续执行。

语法:

fork 
  线程1 
  线程2 
  线程3 
join_any

示例代码:

$display("[%0t] Thread_T1: Starting of fork_join_any", $time);
a = "Kapu";
c = "Malpe";
fork:FORK_F1 
  begin:BEGIN_B2 
    #0 $display("[%0t] Thread_T2: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d); 
    begin:BEGIN_B3 
      b <= a; 
      #1 $display("[%0t] Thread_T3: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d); 
    end:BEGIN_B3 
  end:BEGIN_B2 
  fork:FORK_F2 
    begin:BEGIN_B4 
      #3 -> e1; 
      $display("[%0t] Thread_T4: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d); 
    end:BEGIN_B4 
  join:FORK_F2 
join_any:FORK_F1
#1 $display("[%0t] Thread_T5: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d);
begin:BEGIN_B5
  wait(e1.triggered);
  d = "Kodi";
  $monitor("[%0t] Thread_T6: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d);
end:BEGIN_B5

Pasted image 20250318222109.png

4. fork-join_none

fork-join_none结构允许父线程与子线程并行执行。父线程不会等待子线程完成,而是立即继续执行。

语法:

fork 
  线程1 
  线程2 
  线程3 
join_none

示例代码:

$display("[%0t] Thread_T1: Starting of fork_join_none", $time);
a = "Kapu";
c = "Malpe";
fork:FORK_F1 
  begin:BEGIN_B2 
    #1 $display("[%0t] Thread_T2: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d); 
    b <= a; 
    #1 $display("[%0t] Thread_T3: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d); 
  end:BEGIN_B2 
  fork:FORK_F2 
    #1 -> e1; 
    $display("[%0t] Thread_T4: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d); 
  join:FORK_F2 
join_none:FORK_F1
#1 $display("[%0t] Thread_T5: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d);
wait(e1.triggered);
d = "Kodi";
$monitor("[%0t] Thread_T6: Values of a =%0s,b =%0s,c =%0s,d =%0s", $time, a, b, c, d);

Pasted image 20250318222116.png

5. 进程控制

SystemVerilog提供了多种构造来控制进程的行为,包括终止和等待其他进程完成。

示例代码:

wait fork:

#1 $display("[%0t] Thread_T1: values of a = %0s,b = %0s,c = %0s", $time, a, b, c);
fork:FORK_F1 
  #2 b <= "Delta"; 
  #0 $display("[%0t] Thread_T2: values of a = %0s,b = %0s,c = %0s", $time, a, b, c); 
  begin:BEGIN_B2 
    #1 -> e1; 
    c = "Hoode"; 
    #1 $display("[%0t] Thread_T3: values of a = %0s,b = %0s,c = %0s", $time, a, b, c); 
  end:BEGIN_B2 
  fork:FORK_F2 
    wait(e1.triggered); 
    #2 $display("[%0t] Thread_T4: values of a = %0s,b = %0s,c = %0s", $time, a, b, c); 
  join:FORK_F2 
  #1 $display("[%0t] Thread_T5: values of a = %0s,b = %0s,c = %0s", $time, a, b, c); 
join_none:FORK_F1 
wait fork; 
#0 $monitor("[%0t] Thread_T6: values of a = %0s,b = %0s,c = %0s", $time, a, b, c);

Pasted image 20250318222128.png

disable fork:

#0 $display("[%0t] Thread_T1: Values of a = %0s,b = %0s,c = %0s", $time, a, b, c);
fork:FORK_F1 
  #3 b <= "Delta"; 
  #4 $display("[%0t] Thread_T2: Values of a = %0s,b = %0s,c = %0s", $time, a, b, c); 
  begin:BEGIN_B2 
    #1 -> e1; 
    c = "Hoode"; 
    #1 $display("[%0t] Thread_T3: Values of a = %0s,b = %0s,c = %0s", $time, a, b, c); 
  end:BEGIN_B2 
  fork:FORK_F2 
    @(e1.triggered); 
    #1 $display("[%0t] Thread_T4: Values of a = %0s,b = %0s,c = %0s", $time, a, b, c); 
  join:FORK_F2 
  #1 $display("[%0t] Thread_T5: Values of a = %0s,b = %0s,c = %0s", $time, a, b, c); 
join_any:FORK_F1 
disable fork; 
#1 $display("[%0t] Thread_T6: ending of fork-join", $time);

Pasted image 20250318222133.png

使用fork-joinfork-join_anyfork-join_none结构,SystemVerilog 提供了强大的并发编程能力。这些结构允许用户灵活地控制多线程的执行顺序和同步。此外,wait forkdisable fork 语句进一步增强了对进程的控制,使得模拟和验证过程更加高效和可控。